 package com.bitoon.basketdudes.web.admin;

import com.bitoon.basketdudes.web.BaseAction;
import com.bitoon.basketdudes.web.jpa.Gashaball;
import com.bitoon.basketdudes.web.jpa.Gashaballitem;
import java.util.List;
import javax.persistence.*;
import org.apache.log4j.Logger;


public class DetalleTiendaItem extends BaseAction {

    private DatoTipoItemTienda item;

    private boolean error;
    private boolean modificar;
    private int id;             //id del item
    private String tipo;        //familia: carta,jugador,sobre,ropa
    private String crear;
    private String accion;
    private boolean insertar;
    private int probabilidad;
    private String id_gs;

    //para recibir los parametros del formulario de modificacion del item
    private String nombre;
    private String descripcion;
    private int nivel;
    private int estado;
    private int rareza;
    private int precio;
    private int puntos;
    private int usos;
    private int dias;
    private String[] objeto;

    private List<DatoTipoItemTienda> listaRopa;
    private List<Gashaballitem> listaGashaballItems;

    private Logger log = Logger.getLogger(DetalleTiendaItem.class);

    //acceso a la clase estatica BaseActionAdmin
    private BaseActionAdmin bsaadmin = BaseActionAdmin.getInstance();

    @Override
    public String execute() {
        String retorno = SUCCESS;

        if (getTipo() != null && getId()!=0) {
            BuscarItem();
            if(getTipo().compareTo("gashaball")==0){
                setListaGashaballItems(dameMisGashaballItems());
            }
        }

        return retorno;
    }

    private void BuscarItem(){

        DatoTipoItemTienda retorno = null;
        EntityManager em = null;

        try {
            em = getBsaadmin().getEmfAdmin().createEntityManager(); // checked

            Query q = null;

            String select_carta = "select c.id as id,m.nombre as nombre,c.descripcion as descripcion," +
                    "c.nivel as nivel,c.estado as estado,c.rareza as rareza,c.precio as precio,c.puntos as puntos,-1 as usos,-1 as dias"+
                    " from basket.carta c join basket.m_carta m on(c.m_carta_id = m.id) where c.id="+getId();

            //sacamos la descripcion siempre que no sea un sobre
            String descrip = "i.descripcion as descripcion,";
            String raro = "i.rareza as rareza,";
            if(getTipo().compareTo("sobre")==0 || getTipo().compareTo("gashaball")==0){
                descrip = "'' as descripcion,";
                raro = "-1 as rareza,";
            }

            //sacamos los usos siempre que sea ropa
            String uses = ",i.usos as usos";
            String days = ",i.dias as dias";
            if(getTipo().compareTo("ropa")!=0){
                uses=",-1 as usos";
                days=",-1 as dias";
            }

            String select_item = "select i.id as id,i.nombre as nombre,"+ descrip +
                    "i.nivel as nivel,i.estado as estado," + raro + "i.precio as precio,i.puntos as puntos"+ uses + days +
                    " from basket." + getTipo() + " i where i.id="+getId();

            if(getTipo().compareTo("carta")==0){
                //log.debug("Actualizo una carta: " + select_carta);
                q = em.createNativeQuery(select_carta,DatoTipoItemTienda.class);
            }else{
                //log.debug("Actualizo una item: " + select_item);
                q = em.createNativeQuery(select_item,DatoTipoItemTienda.class);
            }

            retorno = new DatoTipoItemTienda();
            retorno = (DatoTipoItemTienda)q.getSingleResult();

            setItem(retorno);

        } catch (Exception e) {
            log.error("[BuscarItem] Error", e);
        } finally {
            try { em.close(); } catch (Exception e) { }
        }
    }

    public String ModificarItem(){
        String retorno = SUCCESS;

        EntityManager em = null;

        log.debug("[ModificarItem] actualizando tipo: " + getTipo());

        try{
            em = getBsaadmin().getEmfAdmin().createEntityManager(); // checked

            Query q = null;

            //si es ropa compruebo que cumpla las reglas usos/dias o si no lo es entro,sino error
            if((getTipo().compareTo("ropa")==0 && comprobarUsosDiasRopa(usos,dias)==true) || getTipo().compareTo("ropa")!=0)
            {
                //tiene todo menos usos y hay que unirla al modelo de carta
                //HACER DOS UPDATES PARA QUITARNOS EL JOIN QUE ES PELIGROSO
                String update_carta = "update basket.carta "
                        + "set descripcion='" + getDescripcion() + "',"
                        + "nivel=" + getNivel()+ ",estado=" + getEstado()+",rareza=" + getRareza() + ","
                        + "precio=" + getPrecio() + ",puntos=" + getPuntos() + " where id="+getId();

                String update_carta2 = "update basket.m_carta set nombre='" + getNombre() + "' where id=(select m_carta_id from basket.carta where id=" + getId() + ")";

                //especial porque tiene todo+usos
                String update_ropa = "update basket.ropa "
                        + "set nombre='" + getNombre() + "',descripcion='" + getDescripcion() + "',"
                        + "nivel=" + getNivel()+ ",estado=" + getEstado()+",rareza=" + getRareza() + ","
                        + "precio=" + getPrecio() + ",puntos=" + getPuntos() + ",usos=" + getUsos()+ ",dias=" + getDias()
                        + " where id="+getId();

                //sobre tien todo menos descripcion,rareza y usos
                String update_sobre = "update basket.sobre "
                        + "set nombre='" + getNombre() + "',nivel=" + getNivel()+ ",estado=" + getEstado()
                        + ",precio=" + getPrecio() + ",puntos=" + getPuntos() + " where id="+getId();

                //tiene todo menos usos
                String update_jugador = "update basket.m_jugador "
                        + "set nombre='" + getNombre() + "',descripcion='" + getDescripcion() + "',"
                        + "nivel=" + getNivel()+ ",estado=" + getEstado()+",rareza=" + getRareza() + ","
                        + "precio=" + getPrecio() + ",puntos=" + getPuntos() + " where id="+getId();

                //gashaball tiene todo menos descripcion y usos
                String update_gashaball = "update basket.gashaball "
                        + "set nombre='" + getNombre() + "',nivel=" + getNivel()+ ",estado=" + getEstado()
                        + ",precio=" + getPrecio() + ",puntos=" + getPuntos() + " where id="+getId();

                em.getTransaction().begin();

                //si es una carta
                if(getTipo().compareTo("carta")==0){
                    q = em.createNativeQuery(update_carta2);
                    q.executeUpdate();
                    q = em.createNativeQuery(update_carta);
                }

                //si es un sobre
                if(getTipo().compareTo("sobre")==0){
                    q = em.createNativeQuery(update_sobre);
                }

                //si es jugador
                if(getTipo().compareTo("m_jugador")==0){
                    q = em.createNativeQuery(update_jugador);
                }

                //si es ropa
                if(getTipo().compareTo("ropa")==0){
                    q = em.createNativeQuery(update_ropa);
                }

                //si es gashaball
                if(getTipo().compareTo("gashaball")==0){
                    q = em.createNativeQuery(update_gashaball);
                    setListaGashaballItems(dameMisGashaballItems());
                }

                q.executeUpdate();

                em.getTransaction().commit();

                setModificar(true);
            }else{
                error=true;
            }
            BuscarItem();

        } catch (Exception e) {
            retorno = ERROR;
            setError(true);
            log.error("[ModificarItem] Error", e);
        } finally {
            try { em.close(); } catch (Exception e) { }
        }

        return retorno;
    }

    private boolean comprobarUsosDiasRopa(int uses,int days){

        /*Reglas de validacion
        El campo Usos no puede ser 0
        El campo Usos no puede ser < -1
        El campo dias no puede ser < 0

        Si el campo Usos vale -1 el campo Días puede ser mayor que 0

        Si el campo Usos es mayor a 0 el campo Días tiene que ser 0
        Si el campo Días es mayor que 0 el campo usos solo puede valer -1.
        */
        boolean sw=true;

        if(uses==0 || uses<-1 || days<0){
            sw=false;
        }else{
            if(uses>0 && days!=0){
                sw=false;
            }
            if(uses!=-1 && days>0){
                sw=false;
            }
        }

        return sw;
    }

    public List<Gashaballitem> dameMisGashaballItems(){
        EntityManager em = null;
        List<Gashaballitem> retorno = null;
        Query q = null;
        Gashaball gasha = null;

        try {
            //log.debug("[dameMisGashaballItems] Mis gashaballitems,id: " + id);
            em = getBsaadmin().getEmfAdmin().createEntityManager(); // checked
            
            //busco el gashaball
            q = em.createNamedQuery("Gashaball.findById");
            q.setParameter("id", (short)id);

            gasha = (Gashaball)q.getSingleResult();

            if(gasha!=null){
                retorno = gasha.getGashaball_items();
                log.debug("[dameMisGashaballItems] gasha.size: "+retorno.size());
            }
        } catch (Exception e) {
            log.error("[dameMisGashaballItems] Error", e);
        } finally {
            try { em.close(); } catch (Exception e) { }
        }

        return retorno;
    }

    public String elegirAccionObjetos(){
        String retorno = "eliminar";

        if(getAccion()!=null && getAccion().compareTo("nueva")==0){
            retorno = "nueva";
        }

        return retorno;
    }


    public String CrearItem(){

        EntityManager em = null;
        Query q = null;
        String retorno = SUCCESS;

        try {
            if(getCrear()!=null && getCrear().compareTo("")!=0){
                log.debug("[CrearItem] creo un " + tipo +" en la BD");
                log.debug("[CrearItem] nombre: " + nombre +" ,estado: "+estado + " puntos: " +
                        puntos +" precio: " + precio + " nivel: " + nivel);

                em = getBsaadmin().getEmfAdmin().createEntityManager(); // checked

                //saco el ultimo id del item pasado
                int ultimo_id = dameUltimoIdItem();

                if(ultimo_id!=-1){
                    em.getTransaction().begin();

                    Object it = null;

                    //Miro que tipo de item es y creo su objeto
                    if(tipo.compareTo("gashaball")==0){
                        ultimo_id++;
                        it = new Gashaball();
                        ((Gashaball)it).setId((short)ultimo_id);
                        ((Gashaball)it).setNombre(nombre);
                        ((Gashaball)it).setCategoriaId(0);
                        ((Gashaball)it).setEstado((short)estado);
                        ((Gashaball)it).setPuntos(puntos);
                        ((Gashaball)it).setPrecio(precio);
                        ((Gashaball)it).setNivel((short)nivel);
                        
                        em.persist((Gashaball)it);
                    }
                    retorno = "success_creado";
                }else{
                    retorno = ERROR;
                }

                //hago la transaccion - creo el ITEM en la BD
                em.getTransaction().commit();
            }
        } catch (Exception e) {
            log.error("[CrearItem] Error", e);
            retorno = ERROR;
        } finally {
            try { em.close(); } catch (Exception e) { }
        }


        return retorno;
    }

    private int dameUltimoIdItem(){

        EntityManager em = null;
        Query q = null;

        int ultimo_id=-1;
        
        try {
            em = getBsaadmin().getEmfAdmin().createEntityManager(); // checked

            q = em.createNativeQuery("select max(id) from basket.gashaball");

            ultimo_id = (Short)q.getSingleResult();

        } catch (Exception e) {
            log.error("[CrearItem] Error", e);
        } finally {
            try { em.close(); } catch (Exception e) { }
        }

        return ultimo_id;
    }

    public String borrarItem(){
        String retorno = SUCCESS;

        EntityManager em = null;
        Query q = null;

        //si se han pasado items a borrar
        if(objeto!=null && objeto.length>0 && objeto[0].compareTo("")!=0){
            try {
                em = getBsaadmin().getEmfAdmin().createEntityManager(); // checked

                Gashaball gs = null;

                for (String o : objeto) {

                    //busco el gashaball
                    q = em.createNamedQuery("Gashaball.findById");
                    q.setParameter("id", (short)Integer.parseInt(o));
                    gs = (Gashaball)q.getSingleResult();

                    if(gs!=null){
                        //primero borro sus gashaball items si los tubiera
                        log.debug("[borrarItem] tiene " + gs.getGashaball_items().size() + " items.");

                        em.getTransaction().begin();
                        for (Gashaballitem gs_item : gs.getGashaball_items()){
                            em.remove(gs_item);
                        }

                        //borro el gashaball
                        gs = em.find(Gashaball.class, gs.getId());
                        em.remove(gs);
                        em.getTransaction().commit();
                    }
                }

            } catch (Exception e) {
                log.error("[CrearItem] Error", e);
            } finally {
                try { em.close(); } catch (Exception e) { }
            }
        }

        return retorno;
    }

    public String InsertarGashaballItem(){
        String retorno = SUCCESS;
        EntityManager em = null;
        Query q = null;

        if(isInsertar()){
            if(objeto!=null && objeto.length>0 && objeto[0].compareTo("")!=0 && probabilidad>0){
                try {
                    em = getBsaadmin().getEmfAdmin().createEntityManager(); // checked

                    em.getTransaction().begin();

                    Gashaballitem gs =null;
                    for (String o : objeto) {
                        log.debug("Insertar el objeto, Item_id: " + o + " g_id: "+ id_gs + " prob: " + probabilidad);
                        //lo buscamos
                        gs = new Gashaballitem();
                        gs.setId((dameUltimoIdGashaballItem()+1));
                        gs.setGashaballId(Integer.parseInt(id_gs));
                        gs.setItemId(Integer.parseInt(o));
                        gs.setItemType(2);
                        gs.setProbability(probabilidad);

                        em.persist(gs);
                    }

                    em.getTransaction().commit();
                    
                    retorno="insert_ok";
                    
                }catch (Exception e) {
                    log.error("[CrearItem] Error", e);
                }finally {
                    try { em.close(); } catch (Exception e) { }
                }
            }
        }else{
            //mostramos solo el formulario de ropa
            setListaRopa(dameListaRopa());
        }

        return retorno;
    }

    public String ModificarGashaballItem(){
        String retorno = SUCCESS;

        EntityManager em = null;
        Query q = null;

        //si se han pasado items a borrar
        if(id_gs!=null && id_gs.compareTo("")!=0){
            try {
                em = getBsaadmin().getEmfAdmin().createEntityManager(); // checked

                Gashaballitem gitem =null;

                //busco el gashaballitem
                q = em.createNamedQuery("Gashaballitem.findById");
                q.setParameter("id", Integer.parseInt(id_gs));
                gitem = (Gashaballitem)q.getSingleResult();

                if(gitem!=null){
                    log.debug("Modifico el objeto, gitem_id: "+ id_gs + " prob: " + probabilidad);
                    gitem.setProbability(probabilidad);

                    em.getTransaction().begin();
                    em.persist(gitem);
                    em.getTransaction().commit();
                }

            } catch (Exception e) {
                log.error("[ModificarGashaballItem] Error", e);
            } finally {
                try { em.close(); } catch (Exception e) { }
            }
        }

        return retorno;
    }



    private int dameUltimoIdGashaballItem(){

        EntityManager em = null;
        Query q = null;

        int ultimo_id=-1;

        try {
            em = getBsaadmin().getEmfAdmin().createEntityManager(); // checked

            q = em.createNativeQuery("select max(id) from basket.gashaballitem");

            ultimo_id = (Integer)q.getSingleResult();

        } catch (Exception e) {
            log.error("[dameUltimoIdGashaballItem] Error", e);
        } finally {
            try { em.close(); } catch (Exception e) { }
        }

        return ultimo_id;
    }

    /** ropa que se puede meter en un gashaball*/
    public List<DatoTipoItemTienda> dameListaRopa(){
        EntityManager em = null;
        List<DatoTipoItemTienda> retorno = null;

        try {
            log.debug("[dameItems] Entro a buscar ropa del gashaball,id: " + id);
            em = getBsaadmin().getEmfAdmin().createEntityManager(); // checked

            Query q = null;

            String select_ropa = "select i.id as id,i.nombre as nombre,'' as descripcion,i.nivel as nivel,i.estado as estado,-1 as rareza,i.precio as precio,i.puntos as puntos,-1 as usos,-1 as dias"+
                                 " from basket.ropa i"+
                                 " where (i.id not in(select gi.item_id"+
                                                    " from basket.gashaball g join basket.gashaballitem gi"+
                                                    " on(g.id=gi.gashaball_id and g.id="+id+")))" +
                                 " order by nivel asc";

            log.debug("[select] " + select_ropa);

            q = em.createNativeQuery(select_ropa,DatoTipoItemTienda.class);

            retorno = (List<DatoTipoItemTienda>)q.getResultList();

        } catch (Exception e) {
            log.error("[dameListaRopa] Error", e);
        } finally {
            try { em.close(); } catch (Exception e) { }
        }

        return retorno;

    }

    public String borrarGashaballItem(){
        String retorno = SUCCESS;

        EntityManager em = null;
        Query q = null;

        log.debug("[borrarGashaballItem] familia:" + tipo);

        //si se han pasado items a borrar
        if(objeto!=null && objeto.length>0 && objeto[0].compareTo("")!=0){
            try {
                em = getBsaadmin().getEmfAdmin().createEntityManager(); // checked

                Gashaballitem gs = null;

                for (String o : objeto) {
                    log.debug("Borrar el objeto gashaballitem: " + o);

                    //busco el gashaballitem
                    q = em.createNamedQuery("Gashaballitem.findById");
                    q.setParameter("id", Integer.parseInt(o));
                    gs = (Gashaballitem)q.getSingleResult();

                    if(gs!=null){
                        em.getTransaction().begin();
                        em.remove(gs);
                        em.getTransaction().commit();
                    }
                }

            } catch (Exception e) {
                log.error("[CrearItem] Error", e);
            } finally {
                try { em.close(); } catch (Exception e) { }
            }
        }

        return retorno;
    }

    public DatoTipoItemTienda getItem() {
        return item;
    }

    public void setItem(DatoTipoItemTienda item) {
        this.item = item;
    }

    public boolean isError() {
        return error;
    }

    public void setError(boolean error) {
        this.error = error;
    }

    public boolean isModificar() {
        return modificar;
    }

    public void setModificar(boolean modificar) {
        this.modificar = modificar;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTipo() {
        return tipo;
    }

    public void setTipo(String tipo) {
        this.tipo = tipo;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getDescripcion() {
        return descripcion;
    }

    public void setDescripcion(String descripcion) {
        this.descripcion = descripcion;
    }

    public int getNivel() {
        return nivel;
    }

    public void setNivel(int nivel) {
        this.nivel = nivel;
    }

    public int getEstado() {
        return estado;
    }

    public void setEstado(int estado) {
        this.estado = estado;
    }

    public int getRareza() {
        return rareza;
    }

    public void setRareza(int rareza) {
        this.rareza = rareza;
    }

    public int getPrecio() {
        return precio;
    }

    public void setPrecio(int precio) {
        this.precio = precio;
    }

    public int getPuntos() {
        return puntos;
    }

    public void setPuntos(int puntos) {
        this.puntos = puntos;
    }

    public int getUsos() {
        return usos;
    }

    public void setUsos(int usos) {
        this.usos = usos;
    }

    public String getCrear() {
        return crear;
    }

    public void setCrear(String crear) {
        this.crear = crear;
    }

    public List<DatoTipoItemTienda> getListaRopa() {
        return listaRopa;
    }

    public void setListaRopa(List<DatoTipoItemTienda> listaRopa) {
        this.listaRopa = listaRopa;
    }

    public String getAccion() {
        return accion;
    }

    public void setAccion(String accion) {
        this.accion = accion;
    }

    public String[] getObjeto() {
        return objeto;
    }

    public void setObjeto(String[] objetos) {
        this.objeto = objetos;
    }

    public List<Gashaballitem> getListaGashaballItems() {
        return listaGashaballItems;
    }

    public void setListaGashaballItems(List<Gashaballitem> listaGashaballItems) {
        this.listaGashaballItems = listaGashaballItems;
    }

    public boolean isInsertar() {
        return insertar;
    }

    public void setInsertar(boolean insertar) {
        this.insertar = insertar;
    }

    public int getProbabilidad() {
        return probabilidad;
    }

    public void setProbabilidad(int probabilidad) {
        this.probabilidad = probabilidad;
    }

    public String getId_gs() {
        return id_gs;
    }

    public void setId_gs(String id_gs) {
        this.id_gs = id_gs;
    }

    public int getDias() {
        return dias;
    }

    public void setDias(int dias) {
        this.dias = dias;
    }

    public BaseActionAdmin getBsaadmin() {
        return bsaadmin;
    }

    public void setBsaadmin(BaseActionAdmin bsaadmin) {
        this.bsaadmin = bsaadmin;
    }
}


